﻿@using System.Reflection
@using StackExchange.Opserver.Controllers
@using StackExchange.Opserver.Data.Dashboard
@using StackExchange.Opserver.Data.Exceptions
@using StackExchange.Opserver.Data.HAProxy
@using StackExchange.Opserver.Data.SQL
@{
    this.SetPageTitle("关于");

    var asm = Assembly.GetAssembly(typeof(GlobalApplication));
    var rev = asm.GetName().Version.ToString(4);
    var buildDate = new FileInfo(asm.Location).LastWriteTime.ToUniversalTime();
    var s = Current.Settings;
    var cacheStats = ExtensionMethods.GetGetSetStatistics();
    var pollingInfo = PollingEngine.GetPollingStatus();
    var currentTheme = Theme.Current;
}
@helper EnabledSpan(bool enabled) {
    <span class="@(enabled ? "text-success" : "text-danger")">@(enabled ? "Enabled" : "Disabled")</span>
}
@helper EnabledLabel(string text, bool enabled) {
    <span class="label label-@(enabled ? "success" : "default")">@text</span>
}
<h5 class="page-header">
    @SiteSettings.SiteNameLong <span class="text-muted">(@SiteSettings.SiteName)</span>
</h5>
<div class="row small">
    <div class="col-md-4">
        <div class="panel panel-default">
            <div class="panel-heading">信息</div>
            <div class="panel-body small">
                <div class="value-block col-xs-4">
                    @rev
                    <label>应用版本</label>
                </div>
                <div class="value-block col-xs-4">
                    @buildDate.ToRelativeTimeSpan()
                    <label>最后发布</label>
                </div>
                <div class="value-block col-xs-4">
                    @GlobalApplication.StartDate.ToRelativeTimeSpan()
                    <label>更新时间</label>
                </div>
                <div class="value-block col-xs-6">
                    @Environment.MachineName
                    <label>服务器</label>
                </div>
                <div class="value-block col-xs-6">
                    Sync: @cacheStats.Item1.ToComma(), Async: @cacheStats.Item2.ToComma(), Errored: @cacheStats.Item3.ToComma()
                    <label>缓存</label>
                </div>
            </div>
        </div>
        <div class="panel panel-default">
            <div class="panel-heading">设置</div>
            <div class="panel-body small">
                <div class="value-block col-xs-4">
                    <form method="POST" action="~/set-theme" class="form-group-sm">
                        <select class="js-theme form-control" name="theme">
                            @foreach (var t in Theme.Options)
                            {
                                <option value="@t" selected="@(t == currentTheme ? "selected" : null)">@t@(t == Theme.Default ? " (Default)" : null)</option>
                            }
                        </select>
                    </form>
                    <label>当前主题</label>
                </div>
            </div>
        </div>
        <script>
            $('.js-theme').change(function () {
                this.form.submit();
            });
        </script>
        <div class="panel panel-default">
            <div class="panel-heading">部件</div>
            <div class="panel-body">
                @EnabledLabel("仪表板", s.Dashboard.Enabled)
                @EnabledLabel("异常", s.Exceptions.Enabled)
                @EnabledLabel("数据库", s.SQL.Enabled)
                @EnabledLabel("Redis", s.Redis.Enabled)
                @EnabledLabel("Elastic", s.Elastic.Enabled)
                @EnabledLabel("HAProxy", s.HAProxy.Enabled)
                @EnabledLabel("HAProxy Traffic", s.HAProxy.Traffic.Enabled)
            </div>
        </div>
    </div>
    <div class="col-md-4">
        <div class="panel panel-default">
            <div class="panel-heading">轮询</div>
            <div class="panel-body small">
                <div class="value-block col-xs-4 @(pollingInfo.BackgroundClass())">
                    @(pollingInfo.IsAlive ? "Alive" : "Dead")
                    <label>线程</label>
                </div>
                <div class="value-block col-xs-4">
                    @pollingInfo.StartTime.ToRelativeTimeSpan()
                    <label>启动</label>
                </div>
                <div class="value-block col-xs-4">
                    @(pollingInfo.LastPollAll?.ToRelativeTimeSpan())
                    <label>最后轮询</label>
                </div>
                <div class="value-block col-xs-4">
                    @pollingInfo.TotalPollers.ToComma()
                    <label>轮询次数</label>
                </div>
                <div class="value-block col-xs-4">
                    @pollingInfo.TotalPollIntervals.ToComma()
                    <label>轮询间隔</label>
                </div>
                <div class="value-block col-xs-4">
                    @pollingInfo.TotalPollers.ToComma()
                    <label>缓存 <span class="text-muted">(<a href="@Url.Action(nameof(HomeController.AboutCaches))">view</a>)</span></label>
                </div>
                <h6 class="page-header">@pollingInfo.NodeCount.ToComma() 节点</h6>
                <ul class="list-group">
                    @foreach (var ng in pollingInfo.NodeBreakdown)
                    {
                        <li class="list-group-item">
                            <span class="badge">@ng.Item2.ToComma()</span>
                            @ng.Item1.Name.Replace("StackExchange.Opserver.Data.", "")
                        </li>
                    }
                </ul>
            </div>
        </div>
    </div>
    <div class="col-md-4">
        <div class="panel panel-default">
            <div class="panel-heading">安全性</div>
            <div class="panel-body small">
                <div class="value-block col-xs-4 @((SecuritySettings.Current.Enabled ? MonitorStatus.Good : MonitorStatus.Warning).BackgroundClass())">
                    @(SecuritySettings.Current.Enabled ? "Enabled" : "Disabled")
                    <label>安全性</label>
                </div>
                <div class="value-block col-xs-4">
                    @Current.User.AccountName
                    <label>当前用户</label>
                </div>
                <div class="value-block col-xs-4">
                    @Current.RequestIP
                    <label>请求IP</label>
                </div>
                <ul class="list-group col-xs-12">
                    <li class="list-group-item">
                        <span class="text-muted">当前角色:</span>
                        @if (Current.User.IsGlobalAdmin)
                        {
                            <strong class="text-success">Global Admin</strong>
                        }
                        else
                        {
                            @Current.User.Role
                        }
                    </li>
                    <li class="list-group-item">
                        <span class="badge">@Current.Security.InternalNetworks.Count.ToComma()</span>
                        <span class="text-muted">内部网络</span>
                    </li>
                    <li class="list-group-item">
                        <span class="text-muted">Admins:</span> @(SiteSettings.AdminGroups?.Replace(";", ", "))
                    </li>
                    <li class="list-group-item">
                        <span class="text-muted">Viewers:</span> @(SiteSettings.ViewGroups?.Replace(";", ", "))
                    </li>
                </ul>
            </div>
        </div>
    </div>
    <div class="col-md-4">
        @if (s.Dashboard.Enabled)
        {
            <div class="panel panel-default">
                <div class="panel-heading">仪表盘</div>
                <div class="panel-body">
                    @foreach (var p in DashboardModule.Providers)
                    {
                        <h6 class="page-header">@p.IconSpan() @p.Name</h6>
                        <ul class="list-group">
                            <li class="list-group-item">
                                <span class="badge">@p.AllNodes.Count.ToComma()</span>
                                节点
                            </li>
                            <li class="list-group-item">
                                <span class="badge">@p.AllNodes.Sum(n => n.Interfaces?.Count).ToComma()</span>
                                接口
                            </li>
                            <li class="list-group-item">
                                <span class="badge">@p.AllNodes.Sum(n => n.Volumes?.Count).ToComma()</span>
                                卷
                            </li>
                            <li class="list-group-item">
                                <span class="badge">@p.AllNodes.Sum(n => n.Apps?.Count).ToComma()</span>
                                应用
                            </li>
                        </ul>
                    }
                </div>
            </div>
        }
    </div>
    @helper SQLInstanceList(SQLInstance instance)
    {
var props = instance.ServerProperties.SafeData(true);
var features = instance.ServerFeatures.SafeData();
    <li class="list-group-item" title="Features:
@if (features == null)
{
@:Error Fetching Features
}
else
{
<text>
sp_WhoIsActive: @features.HasSPWhoIsActive.ToString()
sp_Blitz: @features.HasSPBlitz.ToString()
sp_BlitzIndex: @features.HasSPBlitzIndex.ToString()
sp_AskBrent: @features.HasSPAskBrent.ToString()
</text>
}">
        @instance.IconSpan() <span class="value">@instance.Name</span> - @props.Version (@props.MachineName)
    </li>
}
    @if (s.SQL.Enabled)
    {
        var clusters = SQLModule.Clusters;
        var instances = SQLModule.StandaloneInstances;
        <div class="col-md-4">
            <div class="panel panel-default panel-@instances.GetWorstStatus().RawClass(showGood: true)">
                <div class="panel-heading">数据库实例</div>
                <div class="panel-body small">
                    <h6 class="page-header">@clusters.Count.Pluralize("可用集群")</h6>
                    @foreach (var cluster in clusters)
                    {
                        <h6>@cluster.IconSpan() @cluster.Name</h6>
                        <ul class="list-group">
                            @foreach (var node in cluster.Nodes)
                            {
                                @SQLInstanceList(node)
                            }
                        </ul>
                    }
                    <h6 class="page-header">@instances.Count.Pluralize("独立节点")</h6>
                    <ul class="list-group">
                        @foreach (var instance in instances)
                        {
                            @SQLInstanceList(instance)
                        }
                    </ul>
                </div>
            </div>
        </div>
    }
    @if (s.Exceptions.Enabled)
    {
        var exceptionStatus = ExceptionsModule.MonitorStatus;
        <div class="col-md-4">
            <div class="panel panel-default panel-@exceptionStatus.RawClass(showGood: true)">
                <div class="panel-heading">异常</div>
                <div class="panel-body small">
                    <ul class="list-group">
                        <li class="list-group-item">
                            <span class="text-muted">Admins:</span>
                            @((s.Exceptions.AdminGroups ?? "None").ColorCode())
                        </li>
                        <li class="list-group-item">
                            <span class="text-muted">Viewers:</span>
                            @((s.Exceptions.ViewGroups ?? "None").ColorCode())
                        </li>
                        <li class="list-group-item">
                            <span class="badge@(s.Exceptions.EnablePreviews ? "" : " alert-warning")">@s.Exceptions.EnablePreviews</span>
                            预览
                        </li>
                        <li class="list-group-item">
                            <span class="badge">@s.Exceptions.RecentSeconds.Pluralize("Second")</span>
                            最近阈值
                        </li>
                        <li class="list-group-item">
                            <span class="badge alert-warning">@s.Exceptions.WarningCount.ToComma() / @s.Exceptions.WarningRecentCount.ToComma() Recent</span>
                            警告阈值
                        </li>
                        <li class="list-group-item">
                            <span class="badge alert-danger">@s.Exceptions.CriticalCount.ToComma() / @s.Exceptions.CriticalRecentCount.ToComma() Recent</span>
                            关键阈值
                        </li>
                    </ul>
                    @foreach (var store in s.Exceptions.Stores)
                    {
                        var es = ExceptionsModule.Stores.First(ess => ess.Name == store.Name);
                        <h6 class="page-header">@es.LastFetch.IconSpan() @store.Name</h6>
                        <ul class="list-group">
                            <li class="list-group-item">
                                <span class="badge">@(store.QueryTimeoutMs.ToComma())ms</span>
                                超时
                            </li>
                            <li class="list-group-item">
                                <span class="badge">@(store.PollIntervalSeconds.ToComma())s</span>
                                轮询间隔
                            </li>
                            <li class="list-group-item">
                                <span class="badge">@(es.Applications.Data?.Sum(a => a.ExceptionCount).ToComma() ?? "0")</span>
                                异常数量
                            </li>
                        </ul>
                    }
                </div>
            </div>
        </div>
    }
    @if (s.HAProxy.Enabled)
    {
        var groups = HAProxyModule.Groups;
        <div class="col-md-4">
            <div class="panel panel-default panel-@HAProxyModule.Groups.GetWorstStatus().RawClass(showGood: true)">
                <div class="panel-heading">HAProxy</div>
                <div class="panel-body small">
                    <ul class="list-group">
                        <li class="list-group-item">
                            <span class="text-muted">Admins:</span>
                            @((s.HAProxy.AdminGroups ?? "None").ColorCode())
                        </li>
                        <li class="list-group-item">
                            <span class="text-muted">Viewers:</span>
                            @((s.HAProxy.ViewGroups ?? "None").ColorCode())
                        </li>
                        <li class="list-group-item">
                            <span class="text-muted">User:</span>
                            @s.HAProxy.User
                        </li>
                        <li class="list-group-item">
                            <span class="badge">@(s.HAProxy.QueryTimeoutMs.ToComma())ms</span>
                            Timeout
                        </li>
                    </ul>
                    @if (groups.Count > 0)
                    {
                        foreach (var g in groups)
                        {
                            <h6 class="page-header">@g.IconSpan() @g.Name</h6>
                            <ul class="list-group">
                                @foreach (var i in g.Instances)
                                {
                                    <li class="list-group-item">
                                        @i.IconSpan() <span class="text-muted">@i.Name:</span> @i.Url
                                    </li>
                                }
                            </ul>
                        }
                    }
                </div>
            </div>
        </div>
    }
</div>